<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css/5-2022-10-25-lidare.css">
</head>

<body>
    <div class="all">
        <div class="box"></div>
        <div class="map"></div>
    </div>
    <div class="reset">重置</div>
    <select class="select">
        <option value="2">2 X 2</option>
        <option value="3" selected>3 X 3</option>
        <option value="6">6 X 6</option>
        <option value="9">9 X 9</option>
    </select>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
    <script>
        jQuery(function () {
            var cat = 3,
                backgroundImage = "url(./images/game.png)",
                width = Math.floor(jQuery(".box").width() / cat),
                height = Math.floor(jQuery(".box").height() / cat),
                where = Math.floor(Math.random() * (cat * cat - 1)),
                left = 0,
                top = 0,
                blank = null,
                mask = [],
                intercept = false,
                allItem = [];
            init(cat);
            function init(cat) {
                jQuery(".box").html("");
                width = Math.floor(jQuery(".box").width() / cat);
                height = Math.floor(jQuery(".box").height() / cat);
                where = Math.floor(Math.random() * (cat * cat - 1));
                left = 0;
                top = 0;
                blank = null;
                mask = [];
                intercept = false;
                jQuery(".map").css({
                    backgroundImage,
                })
                allItem = [];
                for (var i = 0; i < cat; i++) {
                    var mas = [];
                    for (var j = 0; j < cat; j++) {
                        var item = jQuery(`<div class="item"></div>`).appendTo(".box").css({
                            width,
                            height
                        });
                        item.css({
                            left: width * j,
                            top: height * i,
                            backgroundImage: where == item.index() ? "" : backgroundImage,
                            backgroundPosition: `-${width * j}px -${height * i}px`
                        });
                        if (where == item.index()) {
                            left = item.position().left;
                            top = item.position().top;
                            blank = item;
                            blank.data({
                                coordinates: [i, j]
                            }).css({
                                zIndex:10
                            });
                        }
                        mask.push(`${item.position().left},${item.position().top}`);
                        mas.push(item);
                    }
                    allItem.push(mas);

                }

                var num = 0;
                while (++num <= 2000) {
                    Roadrunner();
                }
                num = 0;
                var toArr = [];
                while (num++ < cat) {
                    toArr = toArr.concat([...allItem[num - 1]]);
                }
                var items = jQuery(".item");
                for (var dot = 0; dot < toArr.length; dot++) {
                    var position = jQuery(items[toArr[dot].index()]).position();
                    jQuery(items[toArr[dot].index()]).css({
                        left: jQuery(items[dot]).position().left,
                        top: jQuery(items[dot]).position().top
                    });
                }
            }
            jQuery(".box").on({
                click: function (e) {
                    if (intercept || e.target == blank[0]) return;
                    intercept = true;
                    var position = jQuery(this).position(),
                        check1 = position.left == left && position.top + height == top,
                        check2 = position.left + width == left && position.top == top,
                        check3 = position.left - width == left && position.top == top,
                        check4 = position.left == left && position.top - height == top;
                    if (check1) {
                        jQuery(this).css({
                            top: position.top + height
                        });
                        blank.css({
                            top: blank.position().top - height
                        })
                    } else if (check2) {
                        jQuery(this).css({
                            left: position.left + width
                        });
                        blank.css({
                            left: blank.position().left - width
                        });
                    } else if (check3) {
                        jQuery(this).css({
                            left: position.left - width
                        });
                        blank.css({
                            left: blank.position().left + width
                        });
                    } else if (check4) {
                        jQuery(this).css({
                            top: position.top - height
                        });
                        blank.css({
                            top: blank.position().top + height
                        });
                    } else {
                        intercept = false;
                        return;
                    }
                },
                transitionend: function (e) {
                    left = blank.position().left;
                    top = blank.position().top;
                    intercept = false;
                    var items = jQuery(".item"),
                        cat = [],
                        check = true;
                    for (var i = 0; i < items.length; i++) {
                        if (mask[i].indexOf(`${jQuery(items[i]).position().left},${jQuery(items[i]).position().top}`) == -1) {
                            check = false;
                            break;
                        }
                    }
                    if (check) {
                        blank.css({
                            backgroundImage,
                            backgroundPosition: `-${blank.position().left}px -${blank.position().top}px`
                        });
                        jQuery(`<div class="mask"></div>`).appendTo(".box");
                    }
                }
            }, ".item");
            jQuery(".reset").on({
                click: function () {
                    init(cat);
                }
            });
            jQuery(".select").on({
                change: function () {
                    cat = parseInt(this.value);
                    init(cat);
                }
            });
            function Roadrunner() {
                var arr = copyArr(allItem, cat),
                    coordinates = blank.data("coordinates"),
                    num = Math.floor(Math.random() * 4);
                switch (num) {
                    case 0:
                        var ma = coordinates[0] - 1;
                        if (ma < 0) break;
                        arr[coordinates[0]][coordinates[1]] = arr[ma][coordinates[1]];
                        arr[ma][coordinates[1]] = blank;
                        coordinates[0]--;
                        break;
                    case 3:
                        var ma = coordinates[0] + 1;
                        if (ma >= cat) break;
                        arr[coordinates[0]][coordinates[1]] = arr[ma][coordinates[1]];
                        arr[ma][coordinates[1]] = blank;
                        coordinates[0]++;
                        break;
                    case 1:
                        var ma = coordinates[1] - 1;
                        if (ma < 0) break;
                        arr[coordinates[0]][coordinates[1]] = arr[coordinates[0]][ma];
                        arr[coordinates[0]][ma] = blank;
                        coordinates[1]--;
                        break;
                    case 2:
                        var ma = coordinates[1] + 1;
                        if (ma >= cat) break;
                        arr[coordinates[0]][coordinates[1]] = arr[coordinates[0]][ma];
                        arr[coordinates[0]][ma] = blank;
                        coordinates[1]++;
                        break;
                }
                allItem = arr;
                function copyArr(allItem, cat) {
                    var arr = [];
                    for (var i = 0; i < cat; i++) {
                        arr[i] = [];
                        for (var j = 0; j < cat; j++) {
                            arr[i][j] = allItem[i][j];
                        }
                    }
                    return arr;
                }
            }
        });
    </script>
</body>

</html>